home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Icon 8.1 / mem / MPW Helpers / Procedures / options.icn < prev    next >
Encoding:
Text File  |  1992-11-08  |  7.1 KB  |  168 lines  |  [TEXT/MPS ]

  1. ############################################################################
  2. #
  3. #       Name:    options.icn
  4. #
  5. #       Title:   Get command-line options
  6. #
  7. #       Authors: Robert J. Alexander and Gregg M. Townsend
  8. #
  9. #       Date:    February 27, 1992
  10. #
  11. ############################################################################
  12. #  
  13. #     options(arg,optstring,errproc) -- Get command line options.
  14. #
  15. #     This procedure separates and interprets command options included in 
  16. #  the main program argument list.  Option names and values are removed
  17. #  from the argument list and returned in a table.
  18. #
  19. #     On the command line, options are introduced by a "-" character.  An
  20. #  option name is either a single printable character, as in "-n" or "-?",
  21. #  or a string of letters, as in "-geometry".  Valueless single-character
  22. #  options may appear in combination, for example as "-qtv".
  23. #
  24. #     Some options require values.  Generally, the option name is one
  25. #  argument and the value appears as the next argument, for example
  26. #  "-F file.txt".   However, with a single-character argument name
  27. #  (as in that example), the value may be concatenated: "-Ffile.txt"
  28. #  is accepted as equivalent.
  29. #  
  30. #     Options may be freely interspersed with non-option arguments.
  31. #  An argument of "-" is treated as a non-option.  The special argument
  32. #  "--" terminates option processing.  Non-option arguments are returned
  33. #  in the original argument list for interpretation by the caller.
  34. #
  35. #     An argument of the form @filename (a "@" immediately followed
  36. #  by a file name) causes options() to replace that argument with
  37. #  arguments retrieved from the file "filename".  Each line of the file
  38. #  is taken as a separate argument, exactly as it appears in the file.
  39. #  Arguments beginning with - are processed as options, and those
  40. #  starting with @ are processed as nested argument files.  An argument
  41. #  of "--" causes all remaining arguments IN THAT FILE ONLY to be
  42. #  treated as non-options (including @filename arguments).
  43. #
  44. #     The parameters of options(arg,optstring,errproc) are:
  45. #  
  46. #       arg         the argument list as passed to the main procedure.
  47. #
  48. #       optstring   a string specifying the allowable options.  This is
  49. #                   a concatenation, with optional spaces between, of
  50. #                   one or more option specs of the form
  51. #                       -name%
  52. #                   where
  53. #                       -       introduces the option
  54. #                       name    is either a string of letters
  55. #                               or any single printable character
  56. #                       %       is one of the following flag characters:
  57. #                               !       No value is required or allowed
  58. #                               :       A string value is required
  59. #                               +       An integer value is required
  60. #                               .       A real value is required
  61. #
  62. #                   The leading "-" may be omitted for a single-character
  63. #                   option.  The "!" flag may be omitted except when
  64. #                   needed to terminate a multi-character name.
  65. #                   Thus, the following optstrings are equivalent:
  66. #                       "-n+ -t -v -q -F: -geometry: -silent"
  67. #                       "n+tvqF:-geometry:-silent"
  68. #                       "-silent!n+tvqF:-geometry:"
  69. #
  70. #                   If "optstring" is omitted any single letter is
  71. #                   assumed to be valid and require no data.
  72. #
  73. #       errproc     a procedure which will be called if an error is
  74. #                   is detected in the command line options.  The
  75. #                   procedure is called with one argument:  a string
  76. #                   describing the error that occurred.  After errproc()
  77. #                   is called, options() immediately returns the outcome
  78. #                   of errproc(), without processing further arguments.
  79. #                   Already processed arguments will have been removed
  80. #                   from "arg".  If "errproc" is omitted, stop() is
  81. #                   called if an error is detected.
  82. #  
  83. #     A table is returned containing the options that were specified.
  84. #  The keys are the specified option names.  The assigned values are the
  85. #  data values following the options converted to the specified type.
  86. #  A value of 1 is stored for options that accept no values.
  87. #  The table's default value is &null.
  88. #
  89. #     Upon return, the option arguments are removed from arg, leaving
  90. #  only the non-option arguments.
  91. #  
  92. ############################################################################
  93.  
  94. procedure options(arg,optstring,errproc)
  95.    local f,fList,fileArg,fn,ignore,optname,opttable,opttype,p,x,option
  96.    #
  97.    #  Initialize.
  98.    #
  99.    /optstring := string(&letters)
  100.    /errproc := stop
  101.    option := table()
  102.    fList := []
  103.    opttable := table()
  104.    #
  105.    #  Scan the option specification string.
  106.    #
  107.    optstring ? {
  108.       while optname := move(1) do {
  109.          if optname == " " then next
  110.          if optname == "-" then
  111.             optname := tab(many(&letters)) | move(1) | break
  112.          opttype := tab(any('!:+.')) | "!"
  113.          opttable[optname] := opttype
  114.          }
  115.       }
  116.    #
  117.    #  Iterate over program invocation argument words.
  118.    #
  119.    while x := get(arg) do {
  120.       if /x then ignore := &null     # if end of args from file, stop ignoring
  121.       else x ? {
  122.          if ="-" & not pos(0) & /ignore then {
  123.             if ="-" & pos(0) then ignore := 1   # ignore following args if --
  124.             else {
  125.                tab(0) ? until pos(0) do {
  126.                   if opttype := \opttable[
  127.                         optname := ((pos(1),tab(0)) | move(1))] then {
  128.                      option[optname] :=
  129.                         if any(':+.',opttype) then {
  130.                            p := "" ~== tab(0) | get(arg) |
  131.                               return errproc(
  132.                                     "No parameter following -" || optname)
  133.                            case opttype of {
  134.                               ":": p
  135.                               "+": integer(p) |
  136.                                  return errproc("-" || optname ||
  137.                                        " needs numeric parameter")
  138.                               ".": real(p) |
  139.                                  return errproc("-" || optname ||
  140.                                        " needs numeric parameter")
  141.                               }
  142.                            }
  143.                         else 1
  144.                      }
  145.                   else return errproc("Unrecognized option: -" || optname)
  146.                   }
  147.                }
  148.             }
  149.          #
  150.          #  If the argument begins with the character "@", fetch option
  151.          #  words from lines of a text file.
  152.          #
  153.          else if ="@" & not pos(0) & /ignore then {
  154.             f := open(fn := tab(0)) |
  155.                return errproc("Can't open " || fn)
  156.             fileArg := []
  157.             while put(fileArg,read(f))
  158.             close(f)
  159.             push(arg)   # push null to signal end of args from file
  160.             while push(arg,pull(fileArg))
  161.             }
  162.          else put(fList,x)
  163.          }
  164.       }
  165.    while push(arg,pull(fList))
  166.    return option
  167. end
  168.